package version2024.medium;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Scanner;
import java.util.Stack;

/**
 * @author sunhl
 * @Description: HJ50 四则运算  ScriptEngine的应用 / 字符串, 基础数学, 栈
 * @Date: created in 2025/1/2 星期四 10:00
 * @Modified By:
 */
public class HJ50_FourOperations {
    public static void main(String[] args) throws ScriptException {
        Scanner scan = new Scanner(System.in);
        String input = scan.nextLine();
        // calcByNashorn(input);
        calcByNormal(input);
    }

    // 使用js引擎的nashorn包计算
    public static void calcByNashorn(String input) throws ScriptException {
        input = input.replace("[", "(");
        input = input.replace("{", "(");
        input = input.replace("}", ")");
        input = input.replace("]", ")");
        ScriptEngine scriptEngine = new
                ScriptEngineManager().getEngineByName("nashorn");
        System.out.println(scriptEngine.eval(input));
    }

    // 手写解析字符串进行计算
    public static void calcByNormal(String s) {
        // 字符串长度, 用于遍历
        int n = s.length();
        // num1用于保存已经计算部分的值
        int num1 = 0;
        // 储存当前符号, +, 1, -, -1
        int o1 = 1;
        // num2用于保存正在计算部分的值, 内化了*/的计算结果
        int num2 = 1;
        // 储存当前符号, *, 1, /, -1
        int o2 = 1;
        // 遇到括号时保存之前计算的值
        Stack<Integer> stk = new Stack<>();

        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            // 遇到数字, 定义num2
            if (Character.isDigit(c)) {
                int cur = 0;
                while (i < n && Character.isDigit(s.charAt(i))) {
                    // 如果有下一位数字, 上一位左移
                    // 0的ASCII码是48, 减字符0可以直接获取到当前数字
                    cur = cur * 10 + (s.charAt(i) - '0');
                    i++;
                }
                // 如果是非数字, 因为i已经加一了, 要减
                i--;
                // num2是保存计算中乘除的结果的, 所以这一步内化了乘除计算
                num2 = (o2 == 1 ? num2 * cur : num2 / cur);
            } else if (c == '*' || c == '/') {
                // 遇到乘除定义o2
                o2 = (c == '*' ? 1 : -1);
            } else if (c == '(' || c == '[' || c == '{') {
                // 遇到左括号, 保存当前结果入栈, 并初始化
                stk.push(num1);
                stk.push(o1);
                stk.push(num2);
                stk.push(o2);

                num1 = 0;
                o1 = 1;
                num2 = 1;
                o2 = 1;
            } else if (c == '+' || c == '-') {
                // 遇到加减, 说明可以计算num1并定义其他几个变量
                if (c == '-'
                        && (i == 0 || s.charAt(i - 1) == '('
                        || s.charAt(i - 1) == '[' || s.charAt(i - 1) == '{')) {
                    // 处理字符串首位是-或者括号内字符串首位是-
                    o1 = -1;
                    continue;
                }
                // 计算num1
                num1 = num1 + o1 * num2;
                o1 = (c == '+' ? 1 : -1);
                num2 = 1;
                o2 = 1;
            } else {
                // 遇到右括号, 则出栈, 并计算num2
                int cur = num1 + o1 * num2;
                o2 = stk.pop();
                num2 = stk.pop();
                o1 = stk.pop();
                num1 = stk.pop();

                num2 = (o2 == 1 ? num2 * cur : num2 / cur);
            }
        }
        System.out.println(num1 + o1 * num2);
    }
}
